﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "GcmpGeometryInterface.h"
#include "GbmpConstants.h"

namespace gcmp
{
    class Vector2d;
    class Vector3d;
    class IFace;
    class ICurve3d;
    class ILine3d;
    class IPlane;
    class IArc3d;
    class ICurve2d;
    class ISurface;
    class IBody;

    /// \brief 几何对象间最小距离距离计算类，用于计算几何对象间的最小距离
    ///
    class GCMP_GEOMETRY_INTERFACE_EXPORT AlgorithmMinimalDistance
    {
    public:

        /// \brief  计算两条三维曲线间的最小距离
        ///
        /// \param pFirstCurve3d                        第一条三维曲线
        /// \param pSeccondCurve3d                      第二条三维曲线
        /// \param minimalDistancePointOnFirstCurve     第一条曲线上的最小距离点
        /// \param minimalDistancePointOnSecondCurve    第二条曲线上的最小距离点
        /// \param minimalDistance                      最小距离
        /// \return    true:成功； false:失败
        static bool Calculate(const ICurve3d* pFirstCurve3d, const ICurve3d* pSeccondCurve3d, Vector3d &minimalDistancePointOnFirstCurve, Vector3d &minimalDistancePointOnSecondCurve,double& minimalDistance);

        /// \brief  计算空间点到三维曲线间的最小距离
        ///
        /// \param pCurve3d                           三维曲线
        /// \param queryPoint                         空间点
        /// \param minimalDistancePointOnCurve        三维曲线上的最小距离点
        /// \param bLimit                             曲线是否有限长
        /// \param pParamOnCurve                      最小距离点在曲线上的参数(指针输入为空时不输出)
        /// \param minimalDistance                    最小距离
        /// \return    true:成功； false:失败
        static bool Calculate(const ICurve3d* pCurve3d, const Vector3d& queryPoint, Vector3d& minimalDistancePointOnCurve, bool bLimit, double* const pParamOnCurve, double& minimalDistance);

        /// \brief  计算二维点到二维曲线间的最小距离
        ///
        /// \param pCurve3d                           二维曲线
        /// \param queryPoint                         二维点
        /// \param minimalDistancePointOnCurve        二维曲线上的最小距离点
        /// \param pParamOnCurve                      最小距离点在曲线上的参数(指针输入为空时不输出)
        /// \param bLimit                             曲线是否有限长
        /// \param minimalDistance                    最小距离
        /// \return    true:成功； false:失败
        static bool Calculate(const ICurve2d* pCurve2d, const Vector2d& queryPoint, Vector2d &minimalDistancePointOnCurve, bool bLimit, double* const pParamOnCurve, double& minimalDistance);

        /// \brief  计算二维曲线间的最小距离
        ///
        /// \param pFirstCurve2d                              第一条二维曲线
        /// \param pSecondCurve2d                             第二条二维曲线
        /// \param minimalDistancePointOnFirstCurve           二维曲线1上的最小距离点
        /// \param minimalDistancePointOnSecondCurve          二维曲线2上的最小距离点
        /// \param minimalDistance                            最小距离
        /// \return    true:成功； false:失败
        static bool Calculate(const ICurve2d* pFirstCurve2d, const ICurve2d* pSecondCurve2d, Vector2d &minimalDistancePointOnFirstCurve, Vector2d &minimalDistancePointOnSecondCurve, double& minimalDistance);

        /// \brief  计算空间点到曲面的最小距离
        ///
        /// \param pSurface                            曲面
        /// \param queryPoint                          三维点
        /// \param minimalDistancePointOnSurface       曲面上的最小距离点
        /// \param bLimit                              曲面范围是否有限
        /// \param pParameterOnSurface                 最小距离点在曲面上的参数(指针输入为空时不输出)
        /// \param minimalDistance                     最小距离
        /// \param dDistanceTolerance                  容差
        /// \return    true:成功； false:失败
        static bool Calculate(const ISurface* pSurface, const Vector3d& queryPoint, Vector3d &minimalDistancePointOnSurface, bool bLimit, Vector2d* const pParameterOnSurface,double& minimalDistance, double dDistanceTolerance = Constants::LENGTH_EPS);

        /// \brief  计算三维曲线到曲面的最小距离
        ///
        /// \param pSurface                            曲面
        /// \param pCurve3d                            三维曲线
        /// \param minimalDistance                     最小距离
        /// \param minimalDistancePointOnSurface       曲面上的最小距离点
        /// \param minimalDistancePointOnCurve         曲线上的最小距离点
        /// \param pParameterOnSurface                 最小距离点在曲面上的参数(指针输入为空时不输出)
        /// \param pParameterOnCurve                   最小距离点在曲线上的参数(指针输入为空时不输出)  
        /// \param distanceTolerance                   距离容差
        /// \return    true:成功； false:失败
        static bool Calculate(const ISurface* pSurface, const ICurve3d* pCurve3d, double& minimalDistance, Vector3d &minimalDistancePointOnSurface, Vector3d &minimalDistancePointOnCurve, Vector2d* pParameterOnSurface = nullptr, double* pParameterOnCurve = nullptr, double distanceTolerance = Constants::LENGTH_EPS);

        /// \brief  计算点到体的最小距离
        ///
        /// \param pBody                                 体
        /// \param queryPoint                            三维点
        /// \param minimalDistancePointOnBody            体上的最小距离点
        /// \param minimalDistance                       最小距离
        /// \param dDistanceTolerance                    容差
        /// \return    true:成功； false:失败
        static bool Calculate(const IBody* pBody, const Vector3d &queryPoint, Vector3d &minimalDistancePointOnBody, double& minimalDistance, double dDistanceTolerance = Constants::LENGTH_EPS);

        /// \brief  计算体到体的最小距离
        /// \param pBody1                         体1
        /// \param pBody2                         体2
        /// \param minimalDistancePointOnBody1    体1上的最小距离点
        /// \param minimalDistancePointOnBody2    体2上的最小距离点
        /// \param minimalDistance                最小距离
        /// \param distanceTolerance              容差
        /// \return bool                          成功与否
        static bool Calculate(
            const IBody* pBody1, 
            const IBody* pBody2, 
            Vector3d &minimalDistancePointOnBody1, 
            Vector3d &minimalDistancePointOnBody2, 
            double& minimalDistance, 
            double distanceTolerance = Constants::LENGTH_EPS
        );


        /// \brief  计算曲线到曲面的最小距离
        ///
        /// \param pSurface1                           曲面1
        /// \param pSurface2                           曲面2
        /// \param minimalDistance                     最短距离
        /// \param minimalDistancePointOnSurface1      曲面1上的最小距离点
        /// \param minimalDistancePointOnSurface2      曲线2上的最小距离点 
        /// \param distanceTolerance                   距离容差
        /// \return    true:成功； false:失败
        static bool Calculate(const ISurface* pSurface1, const ISurface* pSurface2, double& minimalDistance, Vector3d &minimalDistancePointOnSurface1, Vector3d &minimalDistancePointOnSurface2,double distanceTolerance = Constants::LENGTH_EPS);

    };
}
